#pragma once

#include "..\cz_def.h"

#define cz_string_SplitT_v1							CZ_COMBINET(cz_string_Split, _v1)
#define cz_string_SplitT_v2							CZ_COMBINET(cz_string_Split, _v2)
#define cz_string_SplitT_v3							CZ_COMBINET(cz_string_Split, _v3)

#define cz_string_TrimLeftT							CZ_COMBINET(cz_string_TrimLeft, )
#define cz_string_TrimRightT						CZ_COMBINET(cz_string_TrimRight, )
#define cz_string_TrimT								CZ_COMBINET(cz_string_Trim, )
#define cz_string_GetLeftT							CZ_COMBINET(cz_string_GetLeft, )
#define cz_string_GetRightT							CZ_COMBINET(cz_string_GetRight, )
#define cz_string_ReverseGetLeftT					CZ_COMBINET(cz_string_ReverseGetLeft, )
#define cz_string_ReverseGetRightT					CZ_COMBINET(cz_string_ReverseGetRight, )

#define cz_string_ToLowerT							CZ_COMBINET(cz_string_ToLower, )
#define cz_string_ToUpperT							CZ_COMBINET(cz_string_ToUpper, )

#define cz_string_U64ToT							CZ_COMBINET(cz_string_U64To, )
#define cz_string_U32ToT							CZ_COMBINET(cz_string_U32To, )
#define cz_string_U16ToT							CZ_COMBINET(cz_string_U16To, )
#define cz_string_U8ToT								CZ_COMBINET(cz_string_U8To, )
#define cz_string_I64ToT							CZ_COMBINET(cz_string_I64To, )
#define cz_string_I32ToT							CZ_COMBINET(cz_string_I32To, )
#define cz_string_I16ToT							CZ_COMBINET(cz_string_I16To, )
#define cz_string_I8ToT								CZ_COMBINET(cz_string_I8To, )

#define cz_string_TToU64							CZ_COMBINET(cz_string_, ToU64)
#define cz_string_TToU32							CZ_COMBINET(cz_string_, ToU32)

#define cz_string_IsVisibleT						CZ_COMBINET(cz_string_IsVisible, )



#define CZ_STRING_NULL								0x00000000

// the value of "flag" in function "cz_string_ReverseGetLeftX" & "cz_string_ReverseGetRightX"
#define CZ_STRING_EMPTY								0x00000001
#define CZ_STRING_INCLUDE							0x00000002

// the value of "flag" in function "cz_string_XToX"
#define CZ_STRING_OCT								0x00000001
#define CZ_STRING_HEX								0x00000002
#define CZ_STRING_PREFIX							0x00000010
#define CZ_STRING_FILL								0x00000020			// valid only if CZ_STRING_HEX is set
#define CZ_STRING_UPPER_CASE						0x00000040			// valid only if CZ_STRING_HEX is set

// split
bool cz_string_SplitW_v1(IN wstringc& wcsSrc, IN wstringc& wcsDelimiters, OUT vector<wstring >& vctDst);
bool cz_string_SplitA_v1(IN stringc& strSrc, IN stringc& strDelimiters, OUT vector<string >& vctDst);

bool cz_string_SplitW_v2(IN wstringc& wcsSrc, IN wstringc& wcsDelimiters, OUT vector<wstring >& vctDst);
bool cz_string_SplitA_v2(IN stringc& strSrc, IN stringc& strDelimiters, OUT vector<string >& vctDst);

bool cz_string_SplitW_v3(IN wstringc& wcsSrc, IN wstringc& wcsDelimiters, OUT vector<wstring >& vctDst);
bool cz_string_SplitA_v3(IN stringc& strSrc, IN stringc& strDelimiters, OUT vector<string >& vctDst);

// sub
wstring cz_string_TrimLeftW(IN wstringc& wcs, IN wstringc& wcsIgnorCharacters);
string cz_string_TrimLeftA(IN stringc& str, IN stringc& strIgnorCharacters);

wstring cz_string_TrimRightW(IN wstringc& wcs, IN wstringc& wcsIgnorCharacters);
string cz_string_TrimRightA(IN stringc& str, IN stringc& strIgnorCharacters);

wstring cz_string_TrimW(IN wstringc& wcs, IN wstringc& wcsIgnorCharacters);
string cz_string_TrimA(IN stringc& str, IN stringc& strIgnorCharacters);

wstring cz_string_GetLeftW(IN wstringc& wcs, IN wchar wcDelimiter, IN u32 flag = CZ_STRING_NULL);
string cz_string_GetLeftA(IN stringc& str, IN char cDelimiter, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_GetRightW(IN wstringc& wcs, IN wchar wcDelimiter, IN u32 flag = CZ_STRING_NULL);
string cz_string_GetRightA(IN stringc& str, IN char cDelimiter, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_ReverseGetLeftW(IN wstringc& wcs, IN wchar wcDelimiter, IN u32 flag = CZ_STRING_NULL);
string cz_string_ReverseGetLeftA(IN stringc& str, IN char cDelimiter, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_ReverseGetRightW(IN wstringc& wcs, IN wchar wcDelimiter, IN u32 flag = CZ_STRING_NULL);
string cz_string_ReverseGetRightA(IN stringc& str, IN char cDelimiter, IN u32 flag = CZ_STRING_NULL);

// convert
wstring cz_string_ToLowerW(IN wstringc& wcs);
string cz_string_ToLowerA(IN stringc& str);

wstring cz_string_ToUpperW(IN wstringc& wcs);
string cz_string_ToUpperA(IN stringc& str);

// num to string
wstring cz_string_U64ToW(IN u64 v, IN u32 flag = CZ_STRING_NULL);
string cz_string_U64ToA(IN u64 v, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_U32ToW(IN u32 v, IN u32 flag = CZ_STRING_NULL);
string cz_string_U32ToA(IN u32 v, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_U16ToW(IN u16 v, IN u32 flag = CZ_STRING_NULL);
string cz_string_U16ToA(IN u16 v, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_U8ToW(IN u8 v, IN u32 flag = CZ_STRING_NULL);
string cz_string_U8ToA(IN u8 v, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_I64ToW(IN i64 v, IN u32 flag = CZ_STRING_NULL);
string cz_string_I64ToA(IN i64 v, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_I32ToW(IN i32 v, IN u32 flag = CZ_STRING_NULL);
string cz_string_I32ToA(IN i32 v, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_I16ToW(IN i16 v, IN u32 flag = CZ_STRING_NULL);
string cz_string_I16ToA(IN i16 v, IN u32 flag = CZ_STRING_NULL);

wstring cz_string_I8ToW(IN i8 v, IN u32 flag = CZ_STRING_NULL);
string cz_string_I8ToA(IN i8 v, IN u32 flag = CZ_STRING_NULL);

// string to num
u64 cz_string_WToU64(IN wstringc& wcs, IN u32 flag = CZ_STRING_NULL);
u64 cz_string_AToU64(IN stringc& str, IN u32 flag = CZ_STRING_NULL);

u32 cz_string_WToU32(IN wstringc& wcs, IN u32 flag = CZ_STRING_NULL);
u32 cz_string_AToU32(IN stringc& str, IN u32 flag = CZ_STRING_NULL);

// check
bool cz_string_IsVisibleW(IN wchar wc);
bool cz_string_IsVisibleA(IN char c);